using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using Microsoft.Extensions.Options;
using UniversalAdminSystem.Infrastructure.Configs;

namespace UniversalAdminSystem.Infrastructure.Services;

public class EmbeddingService
{
    private readonly TongyiConfig _tongyiConfig;
    private readonly HttpClient _httpClient;

    public EmbeddingService(IOptions<TongyiConfig> tongyiConfig, IHttpClientFactory httpClientFactory)
    {
        _tongyiConfig = tongyiConfig.Value;
        _httpClient = httpClientFactory.CreateClient("EmbeddingClient");
        _httpClient.BaseAddress = new Uri(_tongyiConfig.BaseUrl);
        _httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {_tongyiConfig.ApiKey}");
        _httpClient.DefaultRequestHeaders.Add("Accept", "application/json");
    }

    public async Task<List<float[]>> GetEmbeddingAsync(List<string> texts)
    {
        HttpRequestMessage request;
        HttpResponseMessage response;
        const int batchSize = 10;
        var allEmbeddings = new List<float[]>();

        for (int i = 0; i < texts.Count; i += batchSize)
        {
            var batch = texts.Skip(i).Take(batchSize).ToArray();
            var payload = new
            {
                model = "text-embedding-v4",
                input = batch,
                encodingFormat = "float"
            };
            Console.WriteLine("Request Body: " + JsonSerializer.Serialize(payload));
            request = new HttpRequestMessage(HttpMethod.Post, $"{_tongyiConfig.BaseUrl}compatible-mode/v1/embeddings")
            {
                Content = new StringContent(JsonSerializer.Serialize(payload, new JsonSerializerOptions
                {
                    PropertyNamingPolicy = JsonNamingPolicy.CamelCase
                }), Encoding.UTF8, "application/json")
            };
            response = await _httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, CancellationToken.None);
            // response.EnsureSuccessStatusCode();
            var json = await response.Content.ReadAsStringAsync();
            Console.WriteLine($"状态码: {response.StatusCode}, 响应: {json}");
            var embeddingResponse = JsonSerializer.Deserialize<EmbeddingResponse>(json, new JsonSerializerOptions
            {
                PropertyNamingPolicy = JsonNamingPolicy.CamelCase
            });
            if (embeddingResponse?.Data != null)
            {
                allEmbeddings.AddRange(embeddingResponse.Data.Select(d => d.Embedding.ToArray()));
            }
        }

        return allEmbeddings;
    }

    public async Task<string> SubmitEmbeddingTaskAsync(string url)
    {
        HttpRequestMessage request;
        HttpResponseMessage response;
        var payload = new
        {
            model = "text-embedding-async-v2",
            input = url,
            parameters = new { textType = "query" }
        };
        request = new HttpRequestMessage(HttpMethod.Post, $"{_tongyiConfig.BaseUrl}api/v1/services/embeddings/text-embedding/text-embedding")
        {
            Content = new StringContent(JsonSerializer.Serialize(payload, new JsonSerializerOptions
            {
                PropertyNamingPolicy = JsonNamingPolicy.CamelCase
            }), Encoding.UTF8, "application/json")
        };
        request.Headers.Add("X-DashScope-Async", "enable");
        response = await _httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, CancellationToken.None);
        response.EnsureSuccessStatusCode();

        var json = await response.Content.ReadAsStringAsync();
        var res = JsonSerializer.Deserialize<AsyncEmbeddingResponse>(json);

        return res.Output.TaskId;
    }

    public async Task<string> WaitForTaskAsync(string taskId, int pollIntervalSeconds = 5)
    {
        while (true)
        {
            var response = await _httpClient.GetAsync($"tasks/{taskId}");
            response.EnsureSuccessStatusCode();

            var json = await response.Content.ReadAsStringAsync();
            var status = JsonSerializer.Deserialize<TaskStatusResponse>(json);

            Console.WriteLine($"任务状态: {status.Output.TaskStatus}");

            if (status.Output.TaskStatus == "SUCCEEDED")
            {
                return status.Output.ResultUrl;
            }
            else if (status.Output.TaskStatus == "FAILED")
            {
                throw new Exception("向量化任务失败");
            }

            await Task.Delay(TimeSpan.FromSeconds(pollIntervalSeconds));
        }
    }

    public async Task<string> DownloadResultAsync(string resultUrl)
    {
        var result = await _httpClient.GetStringAsync(resultUrl);
        return result;
    }
}
public class EmbeddingResponse
{
    public string Id { get; set; }

    public List<EmbeddingData> Data { get; set; }

    public string Object { get; set; }

    public string Model { get; set; }

    public Usage Usage { get; set; }

}

public class EmbeddingData
{
    public string Object { get; set; }
    public int Index { get; set; }
    public List<float> Embedding { get; set; }
}

public class Usage
{
    public int PromptTokens { get; set; }

    public int TotalTokens { get; set; }
}

public class AsyncEmbeddingResponse
{
    public string RequestId { get; set; }
    public OutputData Output { get; set; }
}

public class OutputData
{
    public string TaskId { get; set; }
    public string TaskStatus { get; set; }
}

public class TaskStatusResponse
{
    public string RequestId { get; set; }
    public TaskOutput Output { get; set; }
}

public class TaskOutput
{
    public string TaskStatus { get; set; }
    public string ResultUrl { get; set; }
}
